package com.imonsoft.sqm.web.business.ipic_system;

import com.imonsoft.common.constant.ConstantSqm;
import com.imonsoft.common.exception.SystemException;
import com.imonsoft.common.util.DateUtil;
import com.imonsoft.sqm.pojo.basedata.Part;
import com.imonsoft.sqm.pojo.business.ipic_system.ClaimView;
import com.imonsoft.sqm.service.business.ipic_system.ClaimViewService;
import com.imonsoft.sqm.service.business.ipic_system.IPICService;
import com.imonsoft.sqm.vo.business.ipic_system.WorstPartVo;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.CategoryLabelPositions;
import org.jfree.chart.labels.StandardCategoryItemLabelGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.BarRenderer;
import org.jfree.chart.servlet.ServletUtilities;
import org.jfree.chart.title.LegendTitle;
import org.jfree.chart.title.TextTitle;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpSession;
import java.awt.*;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.*;
import java.util.List;

@Controller
@RequestMapping("/business/ipic_system/worst_part")
public class WorstPartController {
    protected final Log logger = LogFactory.getLog(getClass());
    @Autowired
    private IPICService ipicService;
    @Autowired
    private ClaimViewService claimViewService;
    private DecimalFormat decimalFormat =new DecimalFormat(",###");//格式化类


    @RequestMapping("/listUI.do")
    public void listUI(ModelMap model,HttpSession session,WorstPartVo worstPartVo) {
        if(StringUtils.isEmpty(worstPartVo.getYear())){
            worstPartVo.setYear(DateUtil.getNowDate().substring(0,4));
        }
        if(StringUtils.isEmpty(worstPartVo.getMonth())){
            worstPartVo.setMonth(DateUtil.getNowDate().substring(5, 7));
        }
        model.put("entity", worstPartVo);

        Map<String, Object> searchMap = new HashMap<String, Object>();//查询条件
        searchMap.put("year", worstPartVo.getYear());
        searchMap.put("type", ConstantSqm.TYPE_CLAIM);

        List<WorstPartVo> worstPartVoList=new ArrayList<WorstPartVo>();
        //一次性把需要的数据全部取出来,用于IPICAccumulate的计算
        List<ClaimView> claimViewList=claimViewService.getAmountUnqualifiedList(ConstantSqm.TYPE_CLAIM, worstPartVo.getYear(), worstPartVo.getMonth());

        Set<WorstPartVo> worstPartVoTree=new TreeSet<WorstPartVo>(new Comparator<WorstPartVo>() {
            @Override
            public int compare(WorstPartVo o1, WorstPartVo o2) {
                int result=(int)(o2.getAmountUnqualifiedAccum()-o1.getAmountUnqualifiedAccum());
                if(result==0){
                    result=(int)(o2.getPpmAccum()-o1.getPpmAccum());
                    if(result==0){
                        result=o2.getPartCode().compareTo(o1.getPartCode());
                    }
                }
                return result;
            }
        });

        for(ClaimView claimView:claimViewList){

            WorstPartVo entity=new WorstPartVo();
            entity.setPartId(claimView.getPartId());
            entity.setPartCode(claimView.getPartCode());
            entity.setPartName(claimView.getPartName());

            searchMap.put("partId", claimView.getPartId());
            searchMap.put("month", worstPartVo.getMonth());
            //--PPMAccumulate--
            double totalNum= ipicService.getIncomingAmountMonth(searchMap);
            double quantity= ipicService.getAmountNotQualifiedMonth(searchMap);
            double ppm=0.0;
            if(totalNum!=0.0){
                ppm=(quantity*1000000.0)/totalNum;
            }
            entity.setPpmAccum(ppm);
            entity.setPpmAccumulate(decimalFormat.format(ppm));

            double amountUnqualifiedAccum=getAmountUnqualifiedAccum(claimViewList,claimView.getPartId());  //再根据条件查询
            entity.setAmountUnqualifiedAccum(amountUnqualifiedAccum);
            entity.setAmountUnqualifiedAccumulate(decimalFormat.format(amountUnqualifiedAccum));
            
            worstPartVoTree.add(entity);
        }

        Iterator<WorstPartVo> iterator=worstPartVoTree.iterator();
        while (iterator.hasNext()){
            worstPartVoList.add(iterator.next());
            if(worstPartVoList.size()==10){
                break;
            }
        }
        model.put("entityList",worstPartVoList);
        model.put("imagePath",drawToJSP(session, worstPartVoList));
    }
    /*public void listUI(ModelMap model,HttpSession session,WorstPartVo worstPartVo) {
        if(StringUtils.isEmpty(worstPartVo.getYear())){
            worstPartVo.setYear(DateUtil.getNowDate().substring(0,4));
        }
        if(StringUtils.isEmpty(worstPartVo.getMonth())){
            worstPartVo.setMonth(DateUtil.getNowDate().substring(5, 7));
        }
        model.put("entity", worstPartVo);


        Map<String, Object> searchMap = new HashMap<String, Object>();//查询条件
        searchMap.put("year", worstPartVo.getYear());
        searchMap.put("type", ConstantSqm.TYPE_CLAIM);
        Map<String,Object> resultMap=new HashMap<String, Object>();//计算结果

        List<WorstPartVo> worstPartVoList=new ArrayList<WorstPartVo>();
        //一次性把需要的数据全部取出来,用于IPICAccumulate的计算
        List<ClaimView> claimViewList=claimViewService.getAmountUnqualifiedList(ConstantSqm.TYPE_CLAIM, worstPartVo.getYear(), worstPartVo.getMonth());

        Set<WorstPartVo> worstPartVoTree=new TreeSet<WorstPartVo>(new Comparator<WorstPartVo>() {
            @Override
            public int compare(WorstPartVo o1, WorstPartVo o2) {
                int result=(int)(o2.getAmountUnqualifiedAccum()-o1.getAmountUnqualifiedAccum());
                if(result==0){
                    result=(int)(o2.getPpmAccum()-o1.getPpmAccum());
                    if(result==0){
                        result=o2.getPartCode().compareTo(o1.getPartCode());
                    }
                }
                return result;
            }
        });
        //List<Part> supplierList=supplierService.findList(null);
        Set<Part> partSet=new HashSet<Part>();
        for(ClaimView claimView:claimViewList){
            Part part=new Part();
            part.setId(claimView.getPartId());
            part.setCode(claimView.getPartCode());
            part.setName(claimView.getPartName());
            partSet.add(part);
        }

        Iterator<Part> partIterator=partSet.iterator();
        while(partIterator.hasNext()){
            Part part=partIterator.next();

            WorstPartVo entity=new WorstPartVo();
            entity.setPartId(part.getId());
            entity.setPartCode(part.getCode());
            entity.setPartName(part.getName());

            searchMap.put("partId", part.getId());
            searchMap.put("month", worstPartVo.getMonth());
            //--PPMAccumulate--
            double totalNumA= ipicService.getIncomingAmountAccumulate(searchMap);
            double quantityA= ipicService.getAmountNotQualifiedAccumulate(searchMap);
            double ppmA=0.0;
            if(totalNumA!=0.0){
                ppmA=(quantityA*1000000.0)/totalNumA;
            }
            entity.setPpmAccum(ppmA);
            entity.setPpmAccumulate(decimalFormat.format(ppmA));

            double amountUnqualifiedAccum=getAmountUnqualifiedAccum(claimViewList,part.getId());  //再根据条件查询
            entity.setAmountUnqualifiedAccum(amountUnqualifiedAccum);
            entity.setAmountUnqualifiedAccumulate(decimalFormat.format(amountUnqualifiedAccum));

            worstPartVoTree.add(entity);
        }

        Iterator<WorstPartVo> iterator=worstPartVoTree.iterator();
        while (iterator.hasNext()){
            worstPartVoList.add(iterator.next());
            if(worstPartVoList.size()==10){
                break;
            }
        }
        model.put("entityList",worstPartVoList);
        model.put("imagePath",drawToJSP(session, worstPartVoList));
    }*/
    private double getAmountUnqualifiedAccum(List<ClaimView> claimViewList,Long partId){
        if(null==claimViewList || null==partId){
            throw new SystemException(ConstantSqm.DATA_ERROR);
        }
        List<ClaimView> resultList=new ArrayList<ClaimView>();
        for(ClaimView claimView:claimViewList){
            if(claimView.getPartId().intValue()==partId.intValue()){
                resultList.add(claimView);
            }
        }
        double amountUnqualified=0.0;
        for(ClaimView claimView:resultList){
            if(claimView.getAmountUnqualified()!=null){
                amountUnqualified=amountUnqualified+claimView.getAmountUnqualified();
            }
        }
        return amountUnqualified;

    }
 
    /**
     * step1:创建 简单数据集对象
     * @return
     */
    private CategoryDataset createDataSet(List<WorstPartVo> worstPartVoList) {
        //创建柱状图数据集
        DefaultCategoryDataset dataset=new DefaultCategoryDataset();
        for(WorstPartVo worstPartVo:worstPartVoList){
            dataset.setValue(worstPartVo.getAmountUnqualifiedAccum(),"Part",worstPartVo.getPartCode());
        }
        return dataset;
    }
    /**
     * step2:创建图表
     * @param dataset
     * @return
     */
    private JFreeChart createChart(CategoryDataset dataset) {
        JFreeChart chart = ChartFactory.createBarChart(   //柱状图
                //JFreeChart chart = ChartFactory.createLineChart3D(  //3D折线图
                "IPIC", //图表的标题
                "",  //目录轴的显示标签
                "",   //数值轴的显示标签
                dataset, //数据集
                PlotOrientation.VERTICAL,  //图表方式：V垂直;H水平
                true, // 是否显示图例
                false, // 是否显示工具提示
                false // 是否生成URL
        );

        //===============为了防止中文乱码：必须设置字体
        chart.setTitle(new TextTitle("Top Ten Worst Part", new Font("宋体", Font.BOLD+Font.ITALIC, 22)));

        LegendTitle legend = chart.getLegend(); // 获取图例
        legend.setItemFont(new Font("宋体", Font.BOLD, 12)); //设置图例的字体，防止中文乱码

        CategoryPlot plot = (CategoryPlot) chart.getPlot(); // 获取柱图的Plot对象(实际图表)
        // 设置柱图背景色（注意，系统取色的时候要使用16位的模式来查看颜色编码，这样比较准确）
        plot.setBackgroundPaint(new Color(255, 255, 204));
        plot.setForegroundAlpha(0.65F); //设置前景色透明度

        // 设置横虚线可见
        plot.setRangeGridlinesVisible(true);
        // 虚线色彩
        plot.setRangeGridlinePaint(Color.gray);

        CategoryAxis categoryAxis = plot.getDomainAxis(); //获取x轴
        categoryAxis.setMaximumCategoryLabelWidthRatio(1.0f);// 横轴上的 Lable 是否完整显示
        categoryAxis.setLabelFont(new Font("宋体", Font.BOLD, 12));//设置字体，防止中文乱码
        categoryAxis.setTickLabelFont(new Font("宋体", Font.BOLD, 12));// 轴数值
        categoryAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_45);//45度倾斜

        plot.getRangeAxis().setLabelFont(new Font("宋体", Font.BOLD, 12)); //Y轴设置字体，防止中文乱码

        //柱图的呈现器
        BarRenderer renderer = new BarRenderer();
        // 设置柱子宽度
        //renderer.setMaximumBarWidth(0.05);
        // 设置柱子高度
        //renderer.setMinimumBarLength(0.2);
        // 设置柱子边框颜色
        renderer.setBaseOutlinePaint(Color.BLACK);
        // 设置柱子边框可见
        renderer.setDrawBarOutline(true);
        //设置每个柱的颜色
        renderer.setSeriesPaint(0, Color.RED);
        //设置每个地区所包含的平行柱的之间距离
        renderer.setItemMargin(0.05);
        // 显示每个柱的数值，并修改该数值的字体属性
        renderer.setIncludeBaseInRange(true);
        renderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());
        renderer.setBaseItemLabelsVisible(true);
        // 设置柱的透明度
        plot.setForegroundAlpha(1.0f);
        //给柱图添加呈现器
        plot.setRenderer(renderer);

        // 没有数据的时候显示的内容
        plot.setNoDataMessage("找不到可用数据...");

        return chart;
    }
    /**
     * step3: 输出图表到tomcat临时目录
     * @param session
     * @param worstPartVoList
     */
    private String drawToJSP(HttpSession session,List<WorstPartVo> worstPartVoList){
        String url ="";
        try {
            JFreeChart chart=createChart(createDataSet(worstPartVoList));
            String fileName = ServletUtilities.saveChartAsPNG(chart, 800, 600, session);
            //ServletUtilities是面向web开发的工具类，返回一个字符串文件名,文件名自动生成，生成好的图片会自动放在服务器（tomcat）的临时文件下（temp）

            url = "/DisplayChart?filename=" + fileName;
            //根据文件名去临时目录下寻找该图片，这里的/DisplayChart路径要与配置文件里用户自定义的<url-pattern>一致
        }catch (SystemException se) {
            logger.info(se.getMessage());
        }catch (IOException e) {
            logger.error(e.getMessage());
        }catch (Exception e) {
            logger.error(e.getMessage());
        }
        return url;
    }
}
